// locutor
// (c) 2009, Normen Müller, normen.mueller@gmail.com  
// $Id: ExtDef.scala 6 2009-11-06 20:06:43Z normen.mueller $
package locutor.parsing.svn.extdef

import java.net.URI

import scaup.Views._

/** The object <code>ExternalParser</code> provides a simple interface for parsing Subversion externals definitions.
 * 
 * @author <a href="mailto:normen.mueller@googlemail.com">Normen M&#xFC;ller</a>
 * @version 0.0.2
 * @todo refactore to locutor.svn similar to scalaxx/ scaup */
object ExtDefParser extends Parser {
  /** Parse the given externals definition string.
   * 
   * @param input the given externals definition string.
   * @return      if parsing succeeded an external defintion; otherwise None */
  def parse(input: String): Option[ExtDef] = parse14(input) match {
    case result @ Some(e) => result
    case None             => parse15(input)
  }
  
  private def parse14(input: String): Option[ExtDef] = phrase(extdef_stmt_14)(new lexical.Scanner(input)) match {
    case Success(result, _) => result
    case _                  => None
  }
  
  private def parse15(input: String): Option[ExtDef] = phrase(extdef_stmt_15)(new lexical.Scanner(input)) match {
    case Success(result, _) => result
    case _                  => None
  }
}

/**
 * @todo document
 * @author <a href="mailto:normen.mueller@googlemail.com">Normen M&#xFC;ller</a>
 * @version 0.0.2 */
case class ExtDef(rev: Long, uri: String, peg: Long, tgt: String) {
  private def n = (s: String) => (if(s.endsWith("/")) s else (s + "/")).toURI
  
  /** Resolve relative externals definitions URLs.
   * 
   * @param rurl the repository URL
   * @param ourl the owner URL, i.e. the URL of the directory the externals definitions are definied on */
  def resolve(rurl: URI, ourl: URI): URI = uri.toSeq match {
    case Seq('.','.','/',_*) => n(ourl.toString).resolve(uri)
    case Seq('^', '/',_*)    => (n(rurl.toString).toString() + uri.substring("^/".length)).toURI
    case Seq('/', '/',_*)    => (n(ourl.toString).getScheme() + ":" + uri).toURI
    case Seq('/', _*)        => ((u: URI) => new URI(u.getScheme, u.getUserInfo, u.getHost, u.getPort, uri, null, null))(n(rurl.toString))
    case _                   => uri.toURI
  }
}
